package com.tencent.iov.cowin.befsale.clue.service.cus.impl;

import com.alibaba.fastjson.JSON;
import com.github.pagehelper.Page;
import com.google.common.collect.Lists;
import com.software.boot.common.entity.Response;
import com.software.boot.common.exception.BusinessException;
import com.software.boot.common.exception.NEError;
import com.software.boot.common.model.dao.OrderField;
import com.software.boot.common.model.dao.PageRequest;
import com.software.boot.common.model.dao.PageResponse;
import com.software.boot.common.util.BeanUtil;
import com.software.boot.common.util.DateTimeUtil;
import com.software.boot.common.util.DateUtil;
import com.software.boot.common.util.EmptyUtils;
import com.software.boot.common.util.JsonUtils;
import com.software.boot.common.util.ValidateUtils;
import com.software.common.config.SearchLocalHeader;
import com.software.common.enums.DeleteEnum;
import com.software.common.enums.SCRMRequestHeaderEnum;
import com.software.common.utils.BasePropertyInjection;
import com.tencent.iov.cowin.befsale.clue.controller.clue.vo.response.ClueOrderResponse;
import com.tencent.iov.cowin.befsale.clue.controller.clue.vo.response.ClueTaskDataHistory;
import com.tencent.iov.cowin.befsale.clue.controller.cus.assembler.DealerCustomerFollowRecordAssembler;
import com.tencent.iov.cowin.befsale.clue.controller.cus.vo.request.AddCustomerFollowPlanRequest;
import com.tencent.iov.cowin.befsale.clue.controller.cus.vo.request.AddCustomerFollowRecordRequest;
import com.tencent.iov.cowin.befsale.clue.controller.cus.vo.request.ClueIntentionGradeDataRequest;
import com.tencent.iov.cowin.befsale.clue.controller.cus.vo.request.CustomerSourceInfo;
import com.tencent.iov.cowin.befsale.clue.controller.cus.vo.request.QueryCustomerFollowPlanRequest;
import com.tencent.iov.cowin.befsale.clue.controller.cus.vo.request.QueryCustomerFollowRecordRequest;
import com.tencent.iov.cowin.befsale.clue.controller.cus.vo.request.UpdateCustomerFollowPlanRequest;
import com.tencent.iov.cowin.befsale.clue.controller.cus.vo.response.CustomerFollowPlanResponse;
import com.tencent.iov.cowin.befsale.clue.controller.cus.vo.response.CustomerFollowRecordResponse;
import com.tencent.iov.cowin.befsale.clue.dao.http.mdquery.MdQueryClient;
import com.tencent.iov.cowin.befsale.clue.dao.http.mdquery.request.QueryCertificateInfoRequest;
import com.tencent.iov.cowin.befsale.clue.dao.http.mdquery.request.QueryVehicleBrandRequest;
import com.tencent.iov.cowin.befsale.clue.dao.http.mdquery.request.QueryVehicleModelRequest;
import com.tencent.iov.cowin.befsale.clue.dao.http.mdquery.request.QueryVehicleSeriesRequest;
import com.tencent.iov.cowin.befsale.clue.dao.http.mdquery.response.CertificateInfoResponse;
import com.tencent.iov.cowin.befsale.clue.dao.http.mdquery.response.DealerResponse;
import com.tencent.iov.cowin.befsale.clue.dao.http.mdquery.response.EmployeeResponse;
import com.tencent.iov.cowin.befsale.clue.dao.http.mdquery.response.VehicleBrandResponse;
import com.tencent.iov.cowin.befsale.clue.dao.http.mdquery.response.VehicleModelResponse;
import com.tencent.iov.cowin.befsale.clue.dao.http.mdquery.response.VehicleSeriesResponse;
import com.tencent.iov.cowin.befsale.clue.dao.http.mdwrite.MdWriteClient;
import com.tencent.iov.cowin.befsale.clue.dao.http.mdwrite.request.AddCertificateInfoRequest;
import com.tencent.iov.cowin.befsale.clue.dao.http.mdwrite.request.UpdateCertificateInfoRequest;
import com.tencent.iov.cowin.befsale.clue.dao.http.tenant.response.DictionariesResponse;
import com.tencent.iov.cowin.befsale.clue.dao.kafka.response.ArrivalOperateRecord;
import com.tencent.iov.cowin.befsale.clue.dao.kafka.response.ClueRecordRequest;
import com.tencent.iov.cowin.befsale.clue.dao.kafka.response.ClueRecordSyncRequest;
import com.tencent.iov.cowin.befsale.clue.dao.kafka.response.DefeatApprovalOperateRecord;
import com.tencent.iov.cowin.befsale.clue.dao.kafka.response.DefeatOperateRecord;
import com.tencent.iov.cowin.befsale.clue.dao.kafka.response.DeliverOperateRecord;
import com.tencent.iov.cowin.befsale.clue.dao.kafka.response.FollowupHistory;
import com.tencent.iov.cowin.befsale.clue.dao.kafka.response.LeadFollowup;
import com.tencent.iov.cowin.befsale.clue.dao.kafka.response.OrderOperateRecord;
import com.tencent.iov.cowin.befsale.clue.dao.kafka.response.PredictOperateRecord;
import com.tencent.iov.cowin.befsale.clue.domain.clue.po.Clue;
import com.tencent.iov.cowin.befsale.clue.domain.clue.po.ClueCustomerCollect;
import com.tencent.iov.cowin.befsale.clue.domain.clue.po.ClueFail;
import com.tencent.iov.cowin.befsale.clue.domain.clue.po.ClueIntentionVehicle;
import com.tencent.iov.cowin.befsale.clue.domain.clue.po.ClueOrder;
import com.tencent.iov.cowin.befsale.clue.domain.cus.po.DealerCustomer;
import com.tencent.iov.cowin.befsale.clue.domain.cus.po.DealerCustomerFollowRecord;
import com.tencent.iov.cowin.befsale.clue.domain.cus.po.PurchaseInvoiceInfo;
import com.tencent.iov.cowin.befsale.clue.domain.cus.vo.CustomerBehaviorStatistical;
import com.tencent.iov.cowin.befsale.clue.repository.clue.ClueFailManager;
import com.tencent.iov.cowin.befsale.clue.repository.cus.DealerCustomerFollowRecordManager;
import com.tencent.iov.cowin.befsale.clue.repository.tenant.TenantManager;
import com.tencent.iov.cowin.befsale.clue.service.clue.ClueCustomerCollectService;
import com.tencent.iov.cowin.befsale.clue.service.clue.ClueFailService;
import com.tencent.iov.cowin.befsale.clue.service.clue.ClueOrderService;
import com.tencent.iov.cowin.befsale.clue.service.clue.ClueService;
import com.tencent.iov.cowin.befsale.clue.service.cus.DealerCustomerFollowPlanService;
import com.tencent.iov.cowin.befsale.clue.service.cus.DealerCustomerFollowRecordService;
import com.tencent.iov.cowin.befsale.clue.service.cus.PurchaseInvoiceInfoService;
import com.tencent.iov.cowin.befsale.clue.service.tenant.DictionaryService;
import com.tencent.iov.cowin.befsale.clue.value.enums.CertificateEnum;
import com.tencent.iov.cowin.befsale.clue.value.enums.ClueOrderStatusEnum;
import com.tencent.iov.cowin.befsale.clue.value.enums.ClueStatsEnum;
import com.tencent.iov.cowin.befsale.clue.value.enums.ExpireStatusEnum;
import com.tencent.iov.cowin.befsale.clue.value.enums.FailReasonEnum;
import com.tencent.iov.cowin.befsale.clue.value.enums.FailStatusEnum;
import com.tencent.iov.cowin.befsale.clue.value.enums.FollowContentEnum;
import com.tencent.iov.cowin.befsale.clue.value.enums.FollowPlanStatusEnum;
import com.tencent.iov.cowin.befsale.clue.value.enums.FollowRecordSecondStatusEnum;
import com.tencent.iov.cowin.befsale.clue.value.enums.FollowRecordStatusEnum;
import com.tencent.iov.cowin.befsale.clue.value.enums.ProdCodeEnum;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.session.RowBounds;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.Optional;

/**
 * @Describe: 经销商线索跟进记录_Service实现层
 * @author: xiamu
 * @created: 2021-12-21 17:29:56
 * @version: 1.0
 */
@Service
@Slf4j
public class DealerCustomerFollowRecordServiceImpl implements DealerCustomerFollowRecordService {

    @Autowired
    private DealerCustomerFollowRecordManager dealerCustomerFollowRecordManager;
    @Autowired
    private DealerCustomerFollowPlanService dealerCustomerFollowPlanService;
    @Autowired
    private ClueOrderService clueOrderService;
    @Autowired
    private ClueFailManager clueFailManager;
    @Autowired
    private ClueFailService clueFailService;
    @Autowired
    private MdQueryClient mdQueryClient;
    @Autowired
    private ClueService clueService;
    @Autowired
    private MdWriteClient mdWriteClient;
    @Autowired
    private ClueCustomerCollectService clueCustomerCollectService;
    @Autowired
    private PurchaseInvoiceInfoService purchaseInvoiceInfoService;
    @Autowired
    private DictionaryService dictionaryService;

    @Value("${properties.intention.grade.type:}")
    private String intentionGradeType;
    @Autowired
    private TenantManager tenantManager;

    @Override
    public DealerCustomerFollowRecord getDetailById(Long id) {
        //验证请求参数
        ValidateUtils.checkObjNull(id, "请求参数不能为空");
        ValidateUtils.checkIntNotNullAndGTZero(id.intValue(), "ID不能为空或小于0");
        //处理业务
        DealerCustomerFollowRecord dealerCustomerFollowRecord = dealerCustomerFollowRecordManager.getDetailById(id);
        if (EmptyUtils.isNotEmpty(dealerCustomerFollowRecord)) {
            return BeanUtil.copy(dealerCustomerFollowRecord, DealerCustomerFollowRecord.class);
        }
        //返回结果
        return null;
    }

    @Override
    public Long insert(AddCustomerFollowRecordRequest request) {
        //验证请求参数
        ValidateUtils.checkObjNull(request, "参数为null");
        ValidateUtils.checkLongGTZero(request.getClueId(), "线索Id不可以为null");
        ValidateUtils.checkObjNull(request.getCusId(), "经销商客户ID为null");
        DealerCustomerFollowRecordAssembler.initAddDealerCustomerFollowRecordRequest(request);

        //填充跟进逾期信息与更新上次跟进计划为完成
        this.fillExpireInfoAndUpdateFollowPlan(request);

        //判断是否有上次跟进计划，若存在更新上次跟进计划为完成状态
        DealerCustomerFollowRecord followRecord = DealerCustomerFollowRecordAssembler.transformVOToPO(request, DealerCustomerFollowRecord.class);


        int result = dealerCustomerFollowRecordManager.insert(followRecord);
        // 封装返回值
        if (result <= 0) {
            throw new BusinessException(NEError.BUSINESS_ERROR, "保存经销商跟进记录失败");
        }
        return followRecord.getId();
    }

    @Override
    public void fillExpireInfoAndUpdateFollowPlan(AddCustomerFollowRecordRequest followRecord) {
        //处理时间
        Date operateTime = EmptyUtils.isEmpty(followRecord.getOperateTime()) ? new Date() : followRecord.getOperateTime();
        followRecord.setOperateTime(operateTime);
        followRecord.setExpireStatus(ExpireStatusEnum.EXPIRY_IN.getCode());
        followRecord.setExpireTime(0L);

        if (EmptyUtils.isEmpty(followRecord.getSecondStatus()) || !FollowRecordSecondStatusEnum.checkFollowExpire(followRecord.getSecondStatus())) {
            return;
        }

        CustomerFollowPlanResponse followPlan;
        //获取跟进计划
        if (EmptyUtils.isEmpty(followRecord.getFollowPlanId()) || followRecord.getFollowPlanId() <= 0) {
            //获取最近一次未完成跟进计划，计算跟进时间
            QueryCustomerFollowPlanRequest queryRequest = new QueryCustomerFollowPlanRequest();
            queryRequest.setClueId(followRecord.getClueId());
            queryRequest.setStatus(FollowPlanStatusEnum.WAIT_FOLLOW.getCode());
            queryRequest.setOrderFields(Lists.newArrayList(new OrderField("id", "DESC")));
            followPlan = dealerCustomerFollowPlanService.getOneByParam(queryRequest);
        } else {
            followPlan = dealerCustomerFollowPlanService.getDetailById(followRecord.getFollowPlanId());
        }

        if (EmptyUtils.isEmpty(followPlan) || EmptyUtils.isEmpty(followPlan.getStatus())
                || FollowPlanStatusEnum.FINISH_FOLLOW.getCode().equals(followPlan.getStatus())) {
            log.info("[DealerCustomerFollowRecordService][fillExpireInfoAndUpdateFollowPlan] 计划跟进不满足条件 followPlan={}",
                    EmptyUtils.isEmpty(followPlan) ? null : JSON.toJSONString(followPlan));
            return;
        }

        //计划跟进为本次记录的下次跟进 不做更新与计算延期状态
        if (followPlan.getId().equals(followRecord.getNextFollowPlanId())) {
            return;
        }
        followRecord.setFollowPlanId(followPlan.getId());

        //填充跟进记录延期信息
        fillExpireInfo(followRecord, followPlan);

        //分配跟进人不做跟进计划操作
        if (FollowRecordSecondStatusEnum.DISTRIBUTION.getCode().equals(followRecord.getSecondStatus())) {
            return;
        }
        UpdateCustomerFollowPlanRequest updateRequest = new UpdateCustomerFollowPlanRequest();
        updateRequest.setId(followPlan.getId());
        updateRequest.setStatus(FollowPlanStatusEnum.FINISH_FOLLOW.getCode());
        int updateFollowPlanResult = dealerCustomerFollowPlanService.update(updateRequest);
        if (updateFollowPlanResult <= 0) {
            throw new BusinessException(NEError.BUSINESS_ERROR, "更新经销商跟进计划信息失败");
        }
    }

    /**
     * 计算跟进记录的过期时间
     *
     * @param followRecord 跟进记录
     * @param followPlan   计划跟进
     */
    private void fillExpireInfo(AddCustomerFollowRecordRequest followRecord, CustomerFollowPlanResponse followPlan) {
        Date operateTime = followRecord.getOperateTime();

        //未逾期
        if (EmptyUtils.isEmpty(followPlan.getPlanFollowTime()) || operateTime.before(followPlan.getPlanFollowTime())) {
            return;
        }

        //设置逾期状态 计算逾期时间
        followRecord.setExpireStatus(ExpireStatusEnum.EXPIRY_OUT.getCode());
        followRecord.setExpireTime((DateUtil.getMillis(operateTime) - DateUtil.getMillis(followPlan.getPlanFollowTime())) / 3600000);

        //判断是否是首次逾期 首次逾期概念-分类1中为跟进的 即 status-> 跟进中的
        if (!FollowRecordStatusEnum.FOLLOW_UP.getCode().equals(followRecord.getStatus())) {
            return;
        }
        DealerCustomerFollowRecord request = new DealerCustomerFollowRecord();
        request.setDeleted(DeleteEnum.INIT.getFlag());
        request.setStatus(FollowRecordStatusEnum.FOLLOW_UP.getCode());
        request.setClueId(followRecord.getClueId());
        List<DealerCustomerFollowRecord> customerFollowRecords = dealerCustomerFollowRecordManager.getListByParam(request);
        if (EmptyUtils.isEmpty(customerFollowRecords)) {
            followRecord.setExpireStatus(ExpireStatusEnum.EXPIRY_OUT_FIRST.getCode());
        }
    }

    @Override
    public int insertBatch(List<AddCustomerFollowRecordRequest> requests) {
        //验证请求参数
        //处理业务
        //封装返回值
        List<DealerCustomerFollowRecord> followRecords = DealerCustomerFollowRecordAssembler.transformPOToResponseVoList(requests, DealerCustomerFollowRecord.class);

        return dealerCustomerFollowRecordManager.insertBatch(followRecords);
    }

    @Override
    public int update(DealerCustomerFollowRecord request) {

        //验证请求参数
        //处理业务
        //返回对象
        DealerCustomerFollowRecordAssembler.initUpdateDealerCustomerFollowRecord(request);
        return dealerCustomerFollowRecordManager.update(request);
    }

    @Override
    public int delete(DealerCustomerFollowRecord request) {
        Long id = request.getId();
        //验证请求参数
        ValidateUtils.checkObjNull(id, "请求参数不能为空");
        ValidateUtils.checkIntNotNullAndGTZero(id.intValue(), "ID不能为空或小于0");
        //处理业务
        DealerCustomerFollowRecord dealerCustomerFollowRecord = new DealerCustomerFollowRecord();
        dealerCustomerFollowRecord.setId(id);
        dealerCustomerFollowRecord.setDeleted(DeleteEnum.DETELED.getFlag());
        //返回对象
        return dealerCustomerFollowRecordManager.update(dealerCustomerFollowRecord);
    }

    @Override
    public List<CustomerFollowRecordResponse> getListByParam(QueryCustomerFollowRecordRequest request) {
        //验证请求参数
        if (EmptyUtils.isEmpty(request)) {
            return Lists.newArrayList();
        }
        DealerCustomerFollowRecord followRecordRequest = DealerCustomerFollowRecordAssembler.transformVOToPO(request, DealerCustomerFollowRecord.class);
        //填充隔离参数
        String dealerId = SearchLocalHeader.getHeader(SCRMRequestHeaderEnum.HEADER_DEALER_ID.getCode());

        if (StringUtils.isNotBlank(dealerId) && !"0".equals(dealerId)) {
            followRecordRequest.setDealerId(dealerId);
        }
        followRecordRequest.setCorpId(SearchLocalHeader.getHeader(SCRMRequestHeaderEnum.HEADER_CORP_ACCOUNTID.getCode()));
        followRecordRequest.setTenantId(SearchLocalHeader.getHeader(SCRMRequestHeaderEnum.HEADER_TENANTID.getCode()));

        //处理业务
        List<DealerCustomerFollowRecord> queryList = dealerCustomerFollowRecordManager.getListByParam(followRecordRequest);
        List<CustomerFollowRecordResponse> recordResponses = BeanUtil.copyByList(queryList, CustomerFollowRecordResponse.class);

        if (CollectionUtils.isEmpty(queryList)) {
            return Lists.newArrayList();
        }

        recordResponses.forEach(followRecordResponse -> {
            //创建 经销商客户信息
            if (FollowRecordSecondStatusEnum.TRANS.getCode().equals(followRecordResponse.getSecondStatus())
                    && EmptyUtils.isNotEmpty(followRecordResponse.getDealerId()) && Integer.parseInt(followRecordResponse.getDealerId()) > 0) {
                Response<DealerResponse> response = mdQueryClient.getDetailById(Integer.parseInt(followRecordResponse.getDealerId()));
                if (EmptyUtils.isEmpty(response) || !Response.CODE_SUCCESS.equals(response.getCode())) {
                    return;
                }
                followRecordResponse.setDealerResponse(response.getData());
            }

            //战败信息
            if (EmptyUtils.isNotEmpty(followRecordResponse.getFailId()) && followRecordResponse.getFailId() > 0) {
                followRecordResponse.setClueFail(clueFailService.getDetailById(followRecordResponse.getFailId()));
            }

            //下定 订单信息
            if (EmptyUtils.isNotEmpty(followRecordResponse.getOrderId()) && followRecordResponse.getOrderId() > 0) {
                followRecordResponse.setClueOrder(clueOrderService.getDetailById(followRecordResponse.getOrderId()));
            }
            //下次计划，计划跟进不为空，查询计划跟进表
            if(followRecordResponse.getNextFollowPlanId()!=null){
                followRecordResponse.setNextPlanRes(dealerCustomerFollowPlanService.getDetailById(followRecordResponse.getNextFollowPlanId()));
            }
        });
        return recordResponses;
    }

    @Override
    public PageResponse<DealerCustomerFollowRecord> getPageByParam(PageRequest<DealerCustomerFollowRecord> request) {
        //验证请求参数
        ValidateUtils.checkObjNull(request, "请求参数不能为空");
        //可以设置排序 query.orderByCreatedTime(true);

        //填充隔离参数
        DealerCustomerFollowRecord query = request.getParamData();
        query.setDealerId(SearchLocalHeader.getHeader(SCRMRequestHeaderEnum.HEADER_DEALER_ID.getCode()));
        query.setCorpId(SearchLocalHeader.getHeader(SCRMRequestHeaderEnum.HEADER_CORP_ACCOUNTID.getCode()));
        query.setTenantId(SearchLocalHeader.getHeader(SCRMRequestHeaderEnum.HEADER_TENANTID.getCode()));

        //处理业务
        RowBounds rowBounds = new RowBounds(request.getPageNum(), request.getPageSize());
        Page<DealerCustomerFollowRecord> queryPageList = dealerCustomerFollowRecordManager.getPageByParam(query, rowBounds);
        PageResponse<DealerCustomerFollowRecord> pageResponse = new PageResponse<>();
        pageResponse.converPageResponse(pageResponse, queryPageList, request);
        pageResponse.setDataList(BeanUtil.copyByList(queryPageList.getResult(), DealerCustomerFollowRecord.class));
        //返回结果
        return pageResponse;
    }

    @Override
    public CustomerFollowRecordResponse getOneByParam(DealerCustomerFollowRecord request) {
        request.setDealerId(SearchLocalHeader.getHeader(SCRMRequestHeaderEnum.HEADER_DEALER_ID.getCode()));
        request.setCorpId(SearchLocalHeader.getHeader(SCRMRequestHeaderEnum.HEADER_CORP_ACCOUNTID.getCode()));
        request.setTenantId(SearchLocalHeader.getHeader(SCRMRequestHeaderEnum.HEADER_TENANTID.getCode()));
        DealerCustomerFollowRecord dealerCustomerFollowRecord = dealerCustomerFollowRecordManager.getOneByParam(request);
        if (EmptyUtils.isEmpty(dealerCustomerFollowRecord)) {
            return null;
        }
        return BeanUtil.copy(dealerCustomerFollowRecord, CustomerFollowRecordResponse.class);
    }

    @Override
    public List<CustomerBehaviorStatistical> statisticalByStatus(Date startDate, Date endDate, List<Integer> statues) {
        ValidateUtils.checkObjNull(startDate, "开始时间不可以为null");
        ValidateUtils.checkObjNull(endDate, "结束时间不可以为null");
        return dealerCustomerFollowRecordManager.statisticalByStatus(startDate, endDate, statues);
    }

    @Override
    public List<CustomerBehaviorStatistical> statisticalBySecondStatus(Date startDate, Date endDate, List<Integer> secondStatues) {
        ValidateUtils.checkObjNull(startDate, "开始时间不可以为null");
        ValidateUtils.checkObjNull(endDate, "结束时间不可以为null");
        return dealerCustomerFollowRecordManager.statisticalBySecondStatus(startDate, endDate, secondStatues);
    }

    /**
     * 以月份分组，查询月份对应的逾期数量
     * add by zly
     *
     * @param clueIntentionGradeDataRequest 统计参数
     * @return 结果
     */
    @Override
    public List<ClueTaskDataHistory> getRecordFollowUpHistoryData(ClueIntentionGradeDataRequest clueIntentionGradeDataRequest) {
        return dealerCustomerFollowRecordManager.getRecordFollowUpHistoryData(clueIntentionGradeDataRequest);
    }

    /**
     * 根据状态统计记录表
     * add by zly
     *
     * @param clueIntentionGradeDataRequest
     * @return
     */
    @Override
    public Integer getRecordFollowUpData(ClueIntentionGradeDataRequest clueIntentionGradeDataRequest) {
        return dealerCustomerFollowRecordManager.getRecordFollowUpData(clueIntentionGradeDataRequest);
    }

    @Transactional(transactionManager = "qw_sale_mastertx", rollbackFor = Exception.class)
    public void handleRecord(ClueRecordRequest recordRequest,Clue clue,CustomerSourceInfo sourceInfo,
                              List<ClueIntentionVehicle> vehicleList,DealerCustomer dealerCustomer,ClueRecordSyncRequest request, Boolean lastFlag) {
        log.info("crm同步线索跟进历史记录,记录数据:[{}]", JSON.toJSONString(recordRequest));
        //本次跟进涉及所有操作人信息
        List<EmployeeResponse> employeeList = getEmployeeList(recordRequest);

        //历史记录操作人信息
        EmployeeResponse historyEmp = new EmployeeResponse();

        if (StringUtils.isNotBlank(recordRequest.getFollowupHistory().getWxUserId())) {
            Optional<EmployeeResponse> first = employeeList.stream().filter(item -> Objects.equals(item.getUserid(), recordRequest.getFollowupHistory().getWxUserId())).findFirst();
            if (first.isPresent()) {
                historyEmp = first.get();
            } else {
                historyEmp.setName("crm_old_sync");
            }
        } else {
            historyEmp.setName("crm_old_sync");
        }

        FollowContentEnum contentEnum = null;

        FollowupHistory history = recordRequest.getFollowupHistory();

        DealerCustomerFollowRecord record = new DealerCustomerFollowRecord();
        record.setSendMqStatus(1);
        record.setTenantId(clue.getTenantId());
        record.setCorpId(clue.getCorpId());
        record.setDealerId(clue.getDealerId());
        record.setCreatedName(historyEmp.getName());
        record.setCreatedBy(historyEmp.getId() == null ? historyEmp.getName() : historyEmp.getId().toString());
        record.setCreatedTime(history.getCreateTime());
        record.setDeleted(DeleteEnum.INIT.getFlag());
        record.setClueId(clue.getId());
        record.setCusId(clue.getCusId());
//        record.setFollowPlanId();
//        record.setNextFollowPlanId();
        record.setSourceInfo(JSON.toJSONString(sourceInfo));
        record.setIntentionGrade(clue.getIntentionGrade());
//        record.setIntentionTags();
        record.setVehInfo(JSON.toJSONString(vehicleList));
        record.setFollowEmpId(dealerCustomer.getFollowEmpId());
        record.setFollowEmpName(dealerCustomer.getFollowEmpName());
//        record.setBefFollowEmpId();
//        record.setBefFollowEmpName();
//        record.setProdCode();
        record.setFollowRemark(history.getFeedBack());

        //更新宽表信息
        ClueCustomerCollect clueCustomerCollect = new ClueCustomerCollect();
        //判断当前线索的followContent
        switch (history.getBizType()) {
            case 0:
                //新建
                /**
                 * 跟进记录状态为新建，二级状态为新建有效线索
                 */
                record.setSecondStatus(FollowRecordSecondStatusEnum.INIT.getCode());
                record.setStatus(FollowRecordStatusEnum.INIT.getCode());
                if (Objects.nonNull(recordRequest.getLeadFollowup())) {
                    insertCluePlan(clue, recordRequest, record, employeeList, historyEmp, clueCustomerCollect);
                }
                if(StringUtils.isNotBlank(request.getLevelFirst())){
                    // 线索等级/意向等级  dictionary 表 module=DETAIL_LEAD_LEVEL
                    String level = request.getLevelFirst();
                    if (!StringUtils.isEmpty(level)) {
                        record.setIntentionGrade("clue_intention_grade_" + level);
                    }
                }
                break;
            case 1:
                //跟进
                /**
                 * 跟进记录的跟进内容为产品介绍，状态为跟进中，二级状态为产品介绍
                 */
                LeadFollowup leadFollowup = recordRequest.getLeadFollowup();
                if (leadFollowup != null && leadFollowup.getFollowType() != null && history.getBizType() == 1) {
                    contentEnum = FollowContentEnum.PRODUCT_INTRO;
                    //再沟通产品介绍的内容映射，followup里的followType为产品介绍的内容
                    StringBuffer prodCode = getOrdCode(leadFollowup.getFollowType());
                    if (prodCode == null) {
                        log.info("crm线索记录迁移,followtype值为:[{}],不迁移", leadFollowup.getFollowType());
                        return;
                    }
                    record.setProdCode(prodCode.toString());
                }
                // TODO: 2022/2/23 跟进默认为产品介绍
                record.setStatus(FollowRecordStatusEnum.FOLLOW_UP.getCode());
                record.setSecondStatus(FollowRecordSecondStatusEnum.FOLLOW_PRODUCT_INTRODUCE.getCode());
                if (Objects.nonNull(recordRequest.getLeadFollowup())) {
                    insertCluePlan(clue, recordRequest, record, employeeList, historyEmp, clueCustomerCollect);
                }
                break;
            case 2:
                //试乘试驾
                /**
                 * 跟进记录的跟进内容为试乘试驾，状态为已到店，二级状态为试乘试驾，试乘试驾的品牌车系，车型，日期和试乘试驾类型
                 * 查询试乘试驾的身份证和驾照，为空则新增，不为空则修改
                 * 设置宽表的试乘试驾时间
                 */
                contentEnum = FollowContentEnum.DRIVE_TEST;
                //处理试乘试驾的证件信息（身份证和驾驶证）
                handleDriveTest(clue, dealerCustomer, recordRequest, record, employeeList, historyEmp);

                PredictOperateRecord predictOperateRecord = recordRequest.getPredictOperateRecord();
                if (predictOperateRecord != null) {
                    clueCustomerCollect.setDriveTime(predictOperateRecord.getCreateTime());
                }

                record.setStatus(FollowRecordStatusEnum.FOLLOW_UP.getCode());
                record.setSecondStatus(FollowRecordSecondStatusEnum.FOLLOW_DRIVE_TEST.getCode());
                break;
            case 4:
                //下订
                /**
                 * 跟进记录的跟进内容为已下订，操作时间为下订时间，状态为跟进中，二级状态为已下订，订单ID为自己表的订单ID
                 * 线索意向登记改为o已下订用户
                 * 线索是否有订单，无则新增，有则修改
                 * 更新宽表的下订时间，意向登记改为o已下订用户
                 */
                if (CollectionUtils.isEmpty(vehicleList)) {
                    log.error("CRM同步线索跟进历史记录，下定时查询线索的意向信息为空");
                    throw new BusinessException(NEError.BUSINESS_ERROR, "CRM同步线索跟进历史记录，下定时查询线索的意向信息为空");
                }
                contentEnum = FollowContentEnum.ORDER;

                //如果下訂的话，意向等级强制为o
                List<DictionariesResponse> dictionariesResponseList = dictionaryService.listDictionary(intentionGradeType);
                DictionariesResponse dictionariesResponse = dictionariesResponseList.stream().filter(d -> d.getName().startsWith("O")).findFirst().orElse(null);
                if (dictionariesResponse != null) {
                    clue.setIntentionGrade(dictionariesResponse.getCode());
                }
                record.setStatus(FollowRecordStatusEnum.FOLLOW_UP.getCode());
                record.setSecondStatus(FollowRecordSecondStatusEnum.FOLLOW_ORDERED.getCode());

                //交车意向等级为o
                clueCustomerCollect.setIntentionGrade(clue.getIntentionGrade());
                clueCustomerCollect.setOrderCreatedTime(record.getOperateTime());

                OrderOperateRecord orderOperateRecord = recordRequest.getOrderOperateRecord();
                if (Objects.nonNull(orderOperateRecord)) {
                    //处理线索订单表信息
                    Long orderId = handleClueOrder(clue, dealerCustomer, orderOperateRecord, vehicleList, employeeList, historyEmp);
                    record.setOrderId(orderId);
                    // TODO: 2022/2/23 下订时间为订单创建时间
                    record.setOperateTime(orderOperateRecord.getCreateTime());
                }
                break;
            case 5:
                //申请战败
                /**
                 * 跟进记录的状态为跟进中，二级状态为申请战败，操作时间为申请战败时间，备注为申请战败的用户反馈
                 * 新增战败申请单
                 * 同步宽表线索状态为战败审核，申请战败人为CRM战败的操作人，战败时间为CRM战败的创建时间，战败备注为CRM用户反馈，战败状态为待审批，跟进次数加1
                 */
                DefeatOperateRecord defeatOperateRecord = recordRequest.getDefeatOperateRecord();
                if (Objects.nonNull(defeatOperateRecord)) {
                    record.setOperateTime(defeatOperateRecord.getCreateTime());
                    record.setRemark(defeatOperateRecord.getFeedback());

                    //新增战败记录
                    ClueFail clueFail = handleClueFail(clue, defeatOperateRecord, employeeList, historyEmp);
                    if(Objects.nonNull(clueFail)){
                        //战败申请成功后--修改搜索宽表信息
                        clueCustomerCollect.setFailEmpId(clueFail.getFollowEmpId());
                        clueCustomerCollect.setFailCreatedTime(clueFail.getCreatedTime());
                        clueCustomerCollect.setFailReasonCodes(clueFail.getFailReasonCodes());
                        clueCustomerCollect.setFailRemark(clueFail.getFailRemark());
                        clueCustomerCollect.setFailStatus(FailStatusEnum.APPROVAL_PENDING.getCode());
                        clueCustomerCollect.setUpdatedName(clueFail.getUpdatedName());
                        clueCustomerCollect.setUpdatedBy(clueFail.getUpdatedBy());
                        clueCustomerCollect.setUpdatedTime(clueFail.getUpdatedTime());
                    }
                }
                record.setStatus(FollowRecordStatusEnum.FOLLOW_UP.getCode());
                record.setSecondStatus(FollowRecordSecondStatusEnum.FOLLOW_FAIL_APPLY.getCode());
                break;
            case 6:
                //战败审批
                /**
                 * 跟进记录的操作时间为CRM审批创建时间，跟进人为战败申请的跟进人，战败同意状态为审批，二级状态为战败同意，战败拒绝状态为审批，二级状态为战败拒绝
                 * SCRM战败申请的审核状态更新
                 * 宽表更新，同意战役，计划跟进时间，计划跟进id，计划跟进时间code，计划跟进内容设置为空，线索状态为已战败，战败状态为同意，审批战败时间为CRM创建时间
                 * 宽表更新，拒绝战败，跟进人为目前客户的跟进人，分配时间为CRM战败审批的创建时间，线索状态为战败申请前的线索状态，战败状态为已拒绝，审批战败时间为CRM创建时间
                 */
                DefeatApprovalOperateRecord approvalOperateRecord = recordRequest.getDefeatApprovalOperateRecord();
                if (Objects.nonNull(approvalOperateRecord)) {
                    record.setOperateTime(approvalOperateRecord.getCreateTime());
                    //更新线索战败申请状态

                    //转化审批状态(1同意，2拒绝)
                    Integer approvalResult = approvalOperateRecord.getApprovalResult();
                    FailStatusEnum failStatusEnum = FailStatusEnum.getByCode(approvalResult);
                    if (failStatusEnum.getCode() == FailStatusEnum.APPROVAL_PENDING.getCode()) {
                        log.error("战败审批跟进记录审批信息，状态为未审批不做处理，CRM线索ID：【{}】，SCRM线索ID：【{}】", request.getLeadId(), clue.getId());
                        break;
                    }

                    //更新宽表信息计划跟进等信息
                    updateCustomerCollect(clueCustomerCollect,dealerCustomer, approvalOperateRecord, failStatusEnum,null);

                    //处理跟进记录信息
                    ClueFail clueFail = getClueFail(request, clue, record, approvalResult);
                    if (clueFail == null) {
                        log.error("战败审批跟进记录审批信息，战败申请为空，CRM线索ID：【{}】，SCRM线索ID：【{}】", request.getLeadId(), clue.getId());
                    }else{
                        //更新战败申请信息
                        updateClueFail(request, clue, approvalResult, clueFail);
                    }
                }
                break;
            case 7:
                //线索分配
                /**
                 * 跟进记录的状态为已分配，二级状态为分配跟进人
                 */
                record.setStatus(FollowRecordStatusEnum.DISTRIBUTION.getCode());
                record.setSecondStatus(FollowRecordSecondStatusEnum.DISTRIBUTION.getCode());
                if(Objects.nonNull(recordRequest.getLeadFollowup())){
                    //筛选出跟进人
                    Optional<EmployeeResponse> first = employeeList.stream().filter(item -> Objects.equals(item.getUserid(), recordRequest.getLeadFollowup().getDistributeToWxUserId())).findFirst();
                    if (first.isPresent()) {
                        record.setFollowEmpId(first.get().getId());
                        record.setFollowEmpName(first.get().getName());
                    }
                }
                if (Objects.nonNull(history.getBizId())) {
                    if (Objects.nonNull(recordRequest.getLeadFollowup())) {
                        insertCluePlan(clue, recordRequest, record, employeeList, historyEmp, clueCustomerCollect);
                    }
                } else if (Objects.nonNull(recordRequest.getLeadFollowup())) {
                    //变更跟进人
                    record.setSecondStatus(FollowRecordSecondStatusEnum.CHANGE_DISTRIBUTION.getCode());
                    //筛选出上次跟进人
                    Optional<EmployeeResponse> optional = employeeList.stream().filter(item -> Objects.equals(item.getUserid(), recordRequest.getLeadFollowup().getWxUserId())).findFirst();
                    if (optional.isPresent()) {
                        record.setBefFollowEmpId(optional.get().getId());
                        record.setBefFollowEmpName(optional.get().getName());
                    }
                }
                break;
            case 8:
                //到店
                /**
                 * 跟进内容为到店，跟进状态为跟进中，二级状态为到店接待，到店时间为CRM到店时间，离店时间为CRM离店时间
                 *
                 */
                contentEnum = FollowContentEnum.CHECKIN;
                ArrivalOperateRecord arrivalOperateRecord = recordRequest.getArrivalOperateRecord();
                if (Objects.nonNull(arrivalOperateRecord)) {
                    record.setCheckinTime(arrivalOperateRecord.getArrivalTime());
                    record.setCheckoutTime(arrivalOperateRecord.getLeaveTime());
                }
                //clue.setStatus(ClueStatsEnum.CHECKIN.getCode());
                record.setStatus(FollowRecordStatusEnum.FOLLOW_UP.getCode());
                record.setSecondStatus(FollowRecordSecondStatusEnum.FOLLOW_CHECKIN.getCode());
                break;
            case 9:
                //交车
                /**
                 * 跟进记录，跟进内同为交车，状态为跟进中，二级状态为已交车，交车名称为CRM交车名称，交车电话为CRM交车电话，交车时间为CRM交车（创建）时间,订单ID为订单表主键
                 *
                 * 订单信息状态变更为已交车
                 * 交车证件信息，无则新增，有则修改
                 * 发票处理，无则新增，有则修改
                 * 设置宽表的计划跟进都为空
                 */
                contentEnum = FollowContentEnum.DELIVERY;
                DeliverOperateRecord deliverOperateRecord = recordRequest.getDeliverOperateRecord();
                if (Objects.nonNull(deliverOperateRecord)) {
                    record.setDeliveryName(deliverOperateRecord.getCustomerName());
                    record.setDeliveryPhone(deliverOperateRecord.getPhone());
                    record.setOperateTime(deliverOperateRecord.getCreateTime());

                    //处理交车的证件信息
                    handleDeliverCard(dealerCustomer, deliverOperateRecord);

                    //发票信息处理-订单信息的状态变更
                    Long orderId = handlePurchaseInvoice(request, clue, deliverOperateRecord, employeeList, historyEmp);
                    record.setOrderId(orderId);
                }
                //如果交车的话，意向等级强制为o
                List<DictionariesResponse> dictionariesResponses = dictionaryService.listDictionary(intentionGradeType);
                DictionariesResponse response = dictionariesResponses.stream().filter(d -> d.getName().startsWith("O")).findFirst().orElse(null);
                if (response != null) {
                    clue.setIntentionGrade(response.getCode());
                }
                record.setStatus(FollowRecordStatusEnum.FOLLOW_UP.getCode());
                record.setSecondStatus(FollowRecordSecondStatusEnum.FOLLOW_DELIVERY.getCode());

                //交车意向等级为o
                clueCustomerCollect.setIntentionGrade(clue.getIntentionGrade());
                //宽表计划跟进为空
                clueCustomerCollect.setPlanFollowId(null);
                clueCustomerCollect.setPlanFollowContent(null);
                clueCustomerCollect.setPlanFollowTime(null);
                clueCustomerCollect.setPlanFollowTimeCode(null);
                break;
            case 10:
                //战败激活
                //更新宽表信息计划跟进等信息
                updateCustomerCollect(clueCustomerCollect,dealerCustomer, null, FailStatusEnum.ACTIVATE,history.getCreateTime());

                //处理跟进记录信息
                ClueFail clueFail = getClueFail(request, clue, record, FailStatusEnum.ACTIVATE.getCode());
                if (clueFail == null) {
                    log.error("战败激活跟进记录，战败申请为空，CRM线索ID：【{}】，SCRM线索ID：【{}】", request.getLeadId(), clue.getId());
                }else{
                    //更新战败申请信息
                    updateClueFail(request, clue, FailStatusEnum.ACTIVATE.getCode(), clueFail);
                }
                break;
        }
        //更新线索状态
        clue.setUpdatedTime(history.getUpdateTime());
        int updateClueResult = clueService.update(clue);
        if (updateClueResult < 0) {
            log.error("同步CRM线索跟进记录，更新线索状态，发生错误，clueID:[{}]", clue.getId());
            //throw new BusinessException(NEError.METHOD_ARGUMENT_INVALIDATE, "crm线索记录同步,更新线索数据发送错误");
        }
        record.setFollowContent(contentEnum == null ? null : contentEnum.getCode().toString());

        //最后一条跟进记录,判断下次跟进时间是否为空,不为空则新增
        if (lastFlag && StringUtils.isNotBlank(record.getFollowContent()) && Objects.nonNull(request.getNextFollowupTime())) {
            //是否有未跟进的计划
            QueryCustomerFollowPlanRequest planRequest = new QueryCustomerFollowPlanRequest();
            planRequest.setClueId(clue.getId());
            planRequest.setDeleted(DeleteEnum.INIT.getFlag());
            planRequest.setStatus(FollowPlanStatusEnum.WAIT_FOLLOW.getCode());
            CustomerFollowPlanResponse planResponse = dealerCustomerFollowPlanService.getOneByParam(planRequest);
            if (Objects.isNull(planResponse)) {
                //手动新增最新的一条跟进计划
                AddCustomerFollowPlanRequest plan = new AddCustomerFollowPlanRequest();
                plan.setClueId(clue.getId());
                plan.setCusId(clue.getCusId());
                //跟上次跟进记录保持一致
                plan.setPlanFollowContent(record.getFollowContent());
                plan.setPlanFollowTime(request.getNextFollowupTime());
//                plan.setPlanFollowTimeCode();
                plan.setTenantId(clue.getTenantId());
                plan.setDealerId(clue.getDealerId());
                plan.setCorpId(clue.getCorpId());
                plan.setStatus(FollowPlanStatusEnum.WAIT_FOLLOW.getCode());
                plan.setCreatedBy(historyEmp.getId() == null ? null : historyEmp.getId().toString());
                plan.setCreatedName(historyEmp.getName());
                plan.setCreatedTime(new Date());
                plan.setDeleted(DeleteEnum.INIT.getFlag());
                Long planId = dealerCustomerFollowPlanService.insert(plan);
                record.setNextFollowPlanId(planId);
                //宽表
                clueCustomerCollect.setPlanFollowId(planId);
                clueCustomerCollect.setPlanFollowContent(record.getFollowContent());
                clueCustomerCollect.setPlanFollowTime(request.getNextFollowupTime());
                clueCustomerCollect.setPlanFollowTimeCode(null);
            }
        }

        ClueCustomerCollect queryClueCollect = new ClueCustomerCollect();
        queryClueCollect.setClueId(clue.getId());
        queryClueCollect.setDeleted(DeleteEnum.INIT.getFlag());
        ClueCustomerCollect exist = clueCustomerCollectService.getOneByParam(queryClueCollect);
        if (EmptyUtils.isEmpty(exist)) {
            log.info("同步CRM线索跟进记录，更新线索集合数据信息不存在");
            //throw new BusinessException(NEError.BUSINESS_ERROR, "同步CRM线索跟进记录，更新线索集合数据信息不存在");
        } else {
            //更新宽表
            long followNum = EmptyUtils.isEmpty(exist.getFollowNum()) ? 0L : exist.getFollowNum();
            clueCustomerCollect.setFollowNum(followNum + 1L);
            clueCustomerCollect.setUpdatedTime(exist.getUpdatedTime());
            clueCustomerCollect.setId(exist.getId());
            clueCustomerCollect.setFollowRemark(record.getFollowRemark());
            clueCustomerCollect.setFollowTime(record.getCreatedTime());
            clueCustomerCollect.setProdCode(record.getProdCode());
            clueCustomerCollect.setFollowContent(contentEnum == null ? null : contentEnum.getCode().toString());
            clueCustomerCollect.setClueId(clue.getId());
            //clueCustomerCollect.setClueStatus(clue.getStatus());
            int collectResult = clueCustomerCollectService.updateByIdAndUpdateTime(clueCustomerCollect);
            if (collectResult <= 0) {
                log.info("更新线索集合信息失败");
                //throw new BusinessException(NEError.BUSINESS_ERROR, "更新线索集合信息失败");
            }
        }
        dealerCustomerFollowRecordManager.insert(record);
    }

    private StringBuffer getOrdCode(Integer followType) {
        StringBuffer prodCode = new StringBuffer();
        prodCode.append(",");
        switch (followType) {
            case 1:
                prodCode.append(ProdCodeEnum.FAIL_REASON_001.getCode());
                break;
            case 2:
                prodCode.append(ProdCodeEnum.FAIL_REASON_002.getCode());
                break;
            case 3:
                prodCode.append(ProdCodeEnum.FAIL_REASON_003.getCode());
                break;
            case 4:
                prodCode.append(ProdCodeEnum.FAIL_REASON_004.getCode());
                break;
            case 5:
                //prodCode.append(ProdCodeEnum.FAIL_REASON_005.getCode());
                return null;
            case 6:
                //prodCode.append(ProdCodeEnum.FAIL_REASON_006.getCode());
                return null;
            case 7:
                prodCode.append(ProdCodeEnum.FAIL_REASON_005.getCode());
                break;
            case 8:
                //prodCode.append(ProdCodeEnum.FAIL_REASON_008.getCode());
                return null;
            case 9:
                prodCode.append(ProdCodeEnum.FAIL_REASON_006.getCode());
                break;
            case 10:
                prodCode.append(ProdCodeEnum.FAIL_REASON_007.getCode());
                break;
            case 11:
                //prodCode.append(ProdCodeEnum.FAIL_REASON_011.getCode());
                return null;
        }
        return prodCode;
    }

    private List<EmployeeResponse> getEmployeeList(ClueRecordRequest recordRequest) {
        //查询本次跟进里所有涉及的操作人empID
        List<String> userIds = new ArrayList<>();
        if (StringUtils.isNotBlank(recordRequest.getFollowupHistory().getWxUserId())) {
            userIds.add(recordRequest.getFollowupHistory().getWxUserId());
        }
        if (Objects.nonNull(recordRequest.getLeadFollowup()) && StringUtils.isNotBlank(recordRequest.getLeadFollowup().getWxUserId())) {
            userIds.add(recordRequest.getLeadFollowup().getWxUserId());
        }
        if (Objects.nonNull(recordRequest.getLeadFollowup()) && StringUtils.isNotBlank(recordRequest.getLeadFollowup().getDistributeToWxUserId())) {
            userIds.add(recordRequest.getLeadFollowup().getDistributeToWxUserId());
        }
        if (Objects.nonNull(recordRequest.getPredictOperateRecord()) && StringUtils.isNotBlank(recordRequest.getPredictOperateRecord().getWxUserId())) {
            userIds.add(recordRequest.getPredictOperateRecord().getWxUserId());
        }
        if (Objects.nonNull(recordRequest.getOrderOperateRecord()) && StringUtils.isNotBlank(recordRequest.getOrderOperateRecord().getWxUserId())) {
            userIds.add(recordRequest.getOrderOperateRecord().getWxUserId());
        }
        if (Objects.nonNull(recordRequest.getDefeatOperateRecord()) && StringUtils.isNotBlank(recordRequest.getDefeatOperateRecord().getWxUserId())) {
            userIds.add(recordRequest.getDefeatOperateRecord().getWxUserId());
        }
        if (Objects.nonNull(recordRequest.getDefeatApprovalOperateRecord()) && StringUtils.isNotBlank(recordRequest.getDefeatApprovalOperateRecord().getWxUserId())) {
            userIds.add(recordRequest.getDefeatApprovalOperateRecord().getWxUserId());
        }
        if (Objects.nonNull(recordRequest.getArrivalOperateRecord()) && StringUtils.isNotBlank(recordRequest.getArrivalOperateRecord().getWxUserId())) {
            userIds.add(recordRequest.getArrivalOperateRecord().getWxUserId());
        }
        if (Objects.nonNull(recordRequest.getDeliverOperateRecord()) && StringUtils.isNotBlank(recordRequest.getDeliverOperateRecord().getWxUserId())) {
            userIds.add(recordRequest.getDeliverOperateRecord().getWxUserId());
        }

        List<EmployeeResponse> employeeList = new ArrayList<>();
        log.info("CRM同步线索跟进记录，查询操作人数据：【{}】", JSON.toJSONString(userIds));
        if (CollectionUtils.isNotEmpty(userIds)) {
            Response<List<EmployeeResponse>> listResponse = mdQueryClient.getUserNameByUserId(userIds);
            log.info("CRM同步线索跟进记录，查询操作人返回：【{}】", JSON.toJSONString(listResponse));
            if (Objects.nonNull(listResponse) && listResponse.getCode() == 0 && CollectionUtils.isNotEmpty(listResponse.getData())) {
                employeeList = listResponse.getData();
            }
        }
        return employeeList;
    }

    private void insertCluePlan(Clue clue, ClueRecordRequest recordRequest, DealerCustomerFollowRecord record,
                                List<EmployeeResponse> employeeList, EmployeeResponse historyEmp, ClueCustomerCollect clueCustomerCollect) {
        //拿到操作人
        String operaName = null;
        String operaId = null;
        if (StringUtils.isNotBlank(recordRequest.getLeadFollowup().getWxUserId())) {
            Optional<EmployeeResponse> first = employeeList.stream().filter(item -> Objects.equals(item.getUserid(), recordRequest.getLeadFollowup().getWxUserId())).findFirst();
            if (first.isPresent()) {
                EmployeeResponse employeeResponse = first.get();
                operaId = employeeResponse.getId().toString();
                operaName = employeeResponse.getName();
            } else {
                operaId = historyEmp.getId() == null ? null : historyEmp.getId().toString();
                operaName = historyEmp.getName();
            }
        }
        //计划跟进时间
        Date followPlan = recordRequest.getLeadFollowup().getFollowPlan();
        AddCustomerFollowPlanRequest plan = new AddCustomerFollowPlanRequest();
        plan.setClueId(clue.getId());
        plan.setCusId(clue.getCusId());
        //跟上次跟进记录保持一致
        plan.setPlanFollowContent(record.getFollowContent());
        plan.setPlanFollowTime(followPlan);
//                plan.setPlanFollowTimeCode();
        plan.setTenantId(clue.getTenantId());
        plan.setDealerId(clue.getDealerId());
        plan.setCorpId(clue.getCorpId());
        plan.setStatus(recordRequest.getLeadFollowup().getStatus());
        plan.setCreatedBy(operaId);
        plan.setCreatedName(operaName);
        plan.setCreatedTime(recordRequest.getLeadFollowup().getCreateTime());
        plan.setDeleted(DeleteEnum.INIT.getFlag());
        Long planId = dealerCustomerFollowPlanService.insert(plan);
        record.setNextFollowPlanId(planId);

        clueCustomerCollect.setPlanFollowId(planId);
        clueCustomerCollect.setPlanFollowContent(record.getFollowContent());
        clueCustomerCollect.setPlanFollowTime(followPlan);
        clueCustomerCollect.setPlanFollowTimeCode(null);
    }

    private ClueFail getClueFail(ClueRecordSyncRequest request, Clue clue, DealerCustomerFollowRecord record, Integer approvalResult) {
        ClueFail queryClueFail = new ClueFail();
        queryClueFail.setClueId(clue.getId());
        queryClueFail.setDeleted(DeleteEnum.INIT.getFlag());
        queryClueFail.setOrderFields(Lists.newArrayList(new OrderField("id", "DESC")));
        ClueFail clueFail = clueFailManager.getOneByParam(queryClueFail);
        if (EmptyUtils.isEmpty(clueFail)) {
            log.error("战败审批跟进记录查询战败申请信息为空，CRM线索ID：【{}】，SCRM线索ID：【{}】", request.getLeadId(), clue.getId());
            //throw new BusinessException(NEError.BUSINESS_ERROR, "线索历史记录同步，查询战败申请记录为空");
        }else {
            //查询申请战败跟进人
            if(clueFail.getFollowEmpId() != null){
                Response<EmployeeResponse> response = mdQueryClient.getDetailById(clueFail.getFollowEmpId());
                if (Objects.nonNull(response) && response.getCode() == 0 && Objects.nonNull(response)) {
                    record.setFollowEmpName(response.getData().getName());
                }
            }
            record.setFailId(clueFail.getId());
            record.setFollowEmpId(clueFail.getFollowEmpId());
        }

        if (approvalResult.intValue() == FailStatusEnum.AGREE.getCode()) {
            record.setStatus(FollowRecordStatusEnum.APPROVAL.getCode());
            record.setSecondStatus(FollowRecordSecondStatusEnum.APPROVAL_FAIL_AGREE.getCode());
        } else if (approvalResult.intValue() == FailStatusEnum.REFUSE.getCode()) {
            record.setStatus(FollowRecordStatusEnum.APPROVAL.getCode());
            record.setSecondStatus(FollowRecordSecondStatusEnum.APPROVAL_FAIL_REFUSED.getCode());
        } else if (approvalResult.intValue() == FailStatusEnum.ACTIVATE.getCode()) {
            record.setStatus(FollowRecordStatusEnum.APPROVAL.getCode());
            record.setSecondStatus(FollowRecordSecondStatusEnum.APPROVAL_FAIL_ACTIVATE.getCode());
            //record.setNextFollowPlanId(request.getPlanFollowId());
        }
        return clueFail;
    }

    private void handleDriveTest(Clue clue, DealerCustomer customerResponse, ClueRecordRequest recordRequest,
                                 DealerCustomerFollowRecord record, List<EmployeeResponse> employeeList, EmployeeResponse historyEmp) {
        PredictOperateRecord predictOperateRecord = recordRequest.getPredictOperateRecord();
        if (Objects.nonNull(predictOperateRecord)) {
            String brandName = null;
            if (Objects.nonNull(predictOperateRecord.getBrandId())) {
                VehicleBrandResponse response = getBrandById(predictOperateRecord.getBrandId().longValue());
                record.setDriveBrandId(predictOperateRecord.getBrandId() == null ? null : predictOperateRecord.getBrandId().longValue());
                brandName = response.getName();
            }

            VehicleSeriesResponse series = getSeriesByName(predictOperateRecord.getSeriesName());
            record.setDriveSeriesId(series.getId());

            VehicleModelResponse model = getModelByName(predictOperateRecord.getModelName());
            record.setDriveModelId(model.getId());
            // TODO: 2022/2/23 试驾年款和配置为空，不同步
//                        record.setDriveYearId();
//                        record.setDriveConfigId();
            record.setOperateTime(predictOperateRecord.getOperateTime());
            record.setTestDrive(predictOperateRecord.getOperationType() == null ? null : Integer.parseInt(predictOperateRecord.getOperationType()));

            //跟进记录的车辆信息JSON
            ClueIntentionVehicle vehicle = new ClueIntentionVehicle();
            vehicle.setClueInitialId(clue.getClueInitialId());
            vehicle.setClueId(clue.getId());
            vehicle.setBrandId(record.getDriveBrandId() == null ? null : record.getDriveBrandId().toString());
            vehicle.setSeriesId(record.getDriveSeriesId() == null ? null : record.getDriveSeriesId().toString());
            vehicle.setSeriesCode(series.getCode());
            vehicle.setModelId(record.getDriveModelId() == null ? null : record.getDriveModelId().toString());
            vehicle.setModelCode(model.getCode());
            vehicle.setBrandName(brandName);
            vehicle.setSeriesName(series.getName());
            vehicle.setModelName(model.getName());
            record.setVehInfo(JSON.toJSONString(vehicle));

            //驾驶证和身份证信息
            handleIdCard(customerResponse, predictOperateRecord, clue, employeeList, historyEmp);
            handleDriving(customerResponse, predictOperateRecord, clue, employeeList, historyEmp);
        }
    }

    /**
     * 处理交车发票信息
     *
     * @param request
     * @param clue
     * @param deliverOperateRecord
     */
    private Long handlePurchaseInvoice(ClueRecordSyncRequest request, Clue clue, DeliverOperateRecord deliverOperateRecord,
                                       List<EmployeeResponse> employeeList, EmployeeResponse historyEmp) {
        //拿到操作人
        String operaName = null;
        String operaId = null;
        if (StringUtils.isNotBlank(deliverOperateRecord.getWxUserId())) {
            Optional<EmployeeResponse> first = employeeList.stream().filter(item -> Objects.equals(item.getUserid(), deliverOperateRecord.getWxUserId())).findFirst();
            if (first.isPresent()) {
                EmployeeResponse employeeResponse = first.get();
                operaId = employeeResponse.getId().toString();
                operaName = employeeResponse.getName();
            } else {
                operaId = historyEmp.getId() == null ? null : historyEmp.getId().toString();
                operaName = historyEmp.getName();
            }
        }

        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd");
        Date invoiceDate = null;
        if (StringUtils.isNotBlank(deliverOperateRecord.getInvoiceDate())) {
            try {
                if(deliverOperateRecord.getInvoiceDate().length() == 8){
                    invoiceDate = dateFormat.parse(deliverOperateRecord.getInvoiceDate());
                }else if(deliverOperateRecord.getInvoiceDate().length() == 13){
                    invoiceDate = new Date(Long.parseLong(deliverOperateRecord.getInvoiceDate()));
                }else if(deliverOperateRecord.getInvoiceDate().length() == 20){
                    invoiceDate = DateTimeUtil.parse(deliverOperateRecord.getInvoiceDate().substring(0,20),"yyyy-MM-dd HH:mm:ss");
                }
            } catch (ParseException e) {
                e.printStackTrace();
                log.info("转换开票日期失败");
            }
        }
        //入库发票信息
        PurchaseInvoiceInfo invoiceInfo = new PurchaseInvoiceInfo();
        invoiceInfo.setInvoiceNum(deliverOperateRecord.getInvoiceNo());
        invoiceInfo.setOpenInvoiceDate(invoiceDate);
        invoiceInfo.setBuyerName(deliverOperateRecord.getCustomerName());
        invoiceInfo.setIdCardOrOrgCode(deliverOperateRecord.getCertNo());
        invoiceInfo.setVin(deliverOperateRecord.getVin());

        ClueOrder orderParam = new ClueOrder();
        orderParam.setClueId(clue.getId());
        orderParam.setDeleted(DeleteEnum.INIT.getFlag());
        OrderField orderField = new OrderField("id", "desc");
        orderParam.setOrderFields(Lists.newArrayList(orderField));
        ClueOrderResponse clueOrder = clueOrderService.getOneByParam(orderParam);
        if (clueOrder == null) {
            log.error("CRM同步处理线索数据，交车记录查询订单信息为空，CRM的线索ID：【{}】,SCRM线索ID：【{}】", request.getLeadId(), clue.getId());
            clueOrder = new ClueOrderResponse();
            //throw new BusinessException(NEError.BUSINESS_ERROR, "CRM同步处理线索数据,处理交车证件信息和发票信息时，查询订单信息为空");

            //没有订单，无法根据订单id查询，所以直接入库新增
            invoiceInfo.setCreatedBy(operaId);
            invoiceInfo.setCreatedName(operaName);
            invoiceInfo.setCreatedTime(deliverOperateRecord.getCreateTime());
            invoiceInfo.setTenantId(clue.getTenantId());
            invoiceInfo.setCorpId(clue.getCorpId());
            invoiceInfo.setDealerId(clue.getDealerId());
            invoiceInfo.setDeleted(DeleteEnum.INIT.getFlag());
            purchaseInvoiceInfoService.insert(invoiceInfo);
        }else {
            //交车修改订单信息的状态
            ClueOrder updateClueOrder = new ClueOrder();
            updateClueOrder.setId(clueOrder.getId());
            updateClueOrder.setStatus(ClueOrderStatusEnum.DELIVERY.getCode());
            int clueOrderResult = clueOrderService.update(updateClueOrder);
            if (clueOrderResult <= 0) {
                log.info("CRM同步处理线索数据-交车失败,更新订单信息的状态失败");
                //throw new BusinessException(NEError.BUSINESS_ERROR, "CRM同步处理线索数据-交车失败,更新订单信息的状态失败");
            }

            invoiceInfo.setOrderId(clueOrder.getId());
            //处理发票信息
            PurchaseInvoiceInfo queryPurchaseInvoiceInfo = new PurchaseInvoiceInfo();
            queryPurchaseInvoiceInfo.setDeleted(DeleteEnum.INIT.getFlag());
            queryPurchaseInvoiceInfo.setOrderId(clueOrder.getId());
            PurchaseInvoiceInfo param = purchaseInvoiceInfoService.getOneByParam(queryPurchaseInvoiceInfo);
            if (param != null) {
                invoiceInfo.setId(param.getId());
                invoiceInfo.setTenantId(clue.getTenantId());
                invoiceInfo.setCorpId(clue.getCorpId());
                invoiceInfo.setDealerId(clue.getDealerId());
                invoiceInfo.setUpdatedName(operaName);
                invoiceInfo.setUpdatedBy(operaId);
                invoiceInfo.setUpdatedTime(deliverOperateRecord.getUpdateTime());
                purchaseInvoiceInfoService.update(invoiceInfo);
            } else {
                invoiceInfo.setCreatedBy(operaId);
                invoiceInfo.setCreatedName(operaName);
                invoiceInfo.setCreatedTime(deliverOperateRecord.getCreateTime());
                invoiceInfo.setTenantId(clue.getTenantId());
                invoiceInfo.setCorpId(clue.getCorpId());
                invoiceInfo.setDealerId(clue.getDealerId());
                invoiceInfo.setDeleted(DeleteEnum.INIT.getFlag());
                purchaseInvoiceInfoService.insert(invoiceInfo);
            }
        }

        return clueOrder.getId();
    }

    /**
     * 处理交车的证件信息
     *
     * @param customerResponse
     * @param deliverOperateRecord
     */
    private void handleDeliverCard(DealerCustomer customerResponse, DeliverOperateRecord deliverOperateRecord) {
        if (StringUtils.isNotBlank(deliverOperateRecord.getCertNo())) {
            //证件号不为空
            Long oneId = null;
            try{
                String oneIdStr = customerResponse.getOneId();
                if(StringUtils.isNotBlank(oneIdStr)){
                    oneId = Long.valueOf(oneIdStr);
                }
            }catch (Exception e) {
                //ignore
            }
            AddCertificateInfoRequest certificateInfo = new AddCertificateInfoRequest();
            certificateInfo.setOneId(oneId);
            certificateInfo.setCusId(customerResponse.getCustomerBaseId());
            certificateInfo.setName(deliverOperateRecord.getCustomerName());
            // TODO: 2022/2/23 目前数据都为空，暂时不做转换处理
            certificateInfo.setSex(customerResponse.getGender() == null ? null : customerResponse.getGender().toString());
//                            certificateInfo.setNation();
//                            certificateInfo.setBirth();
//                            certificateInfo.setAddress();
            certificateInfo.setCardId(deliverOperateRecord.getCertNo());
//                            certificateInfo.setNationality();
//                            certificateInfo.setFirstIssueDate();
//                            certificateInfo.setQuasiDrivingType();
//                            certificateInfo.setStartValidityDate("");
//                            certificateInfo.setEndValidityDate();
//                            certificateInfo.setDataSources();
            certificateInfo.setUrl(deliverOperateRecord.getCertPicUrl());
            Integer certificateType = null;
            Integer certType = deliverOperateRecord.getCertType();
            switch (certType) {
                case 1:
                    certificateType = CertificateEnum.ID_CARD.getCode();
                    break;
                case 2:
                    certificateType = CertificateEnum.OFFICERS.getCode();
                    break;
                case 3:
                    certificateType = CertificateEnum.HMTO.getCode();
                    break;
                case 4:
                    certificateType = CertificateEnum.ENTERPRISE.getCode();
                    break;

            }
            certificateInfo.setCertificateType(certificateType);

            QueryCertificateInfoRequest queryCertificateInfoRequest = new QueryCertificateInfoRequest();
            queryCertificateInfoRequest.setOneId(oneId);
            queryCertificateInfoRequest.setDeleted(DeleteEnum.INIT.getFlag());
            queryCertificateInfoRequest.setCertificateType(certificateType);
            log.info("调用mdQuery 查询证件表,入参：{}", JsonUtils.object2JSON(queryCertificateInfoRequest));
            CertificateInfoResponse certificateInfoResponse = mdQueryClient.getOneByParam(queryCertificateInfoRequest).getData();
            if (certificateInfoResponse != null) {
                Long id = certificateInfoResponse.getId();
                certificateInfo.setId(id);
                BasePropertyInjection.updatePropertyInjection(certificateInfo);
                log.info("调用mdWrite update证件表,入参：{}", JsonUtils.object2JSON(certificateInfo));
                mdWriteClient.update(BeanUtil.copy(certificateInfo, UpdateCertificateInfoRequest.class));
            } else {
                BasePropertyInjection.savePropertyInjection(certificateInfo);
                certificateInfo.setDeleted(DeleteEnum.INIT.getFlag());
                log.info("调用mdWrite add证件表,入参：{}", JsonUtils.object2JSON(certificateInfo));
                mdWriteClient.add(certificateInfo);
            }
        }
    }

    /**
     * CRM跟进记录同步更新宽表信息
     *
     * @param customerResponse
     * @param approvalOperateRecord
     * @param failStatusEnum
     */
    private void updateCustomerCollect(ClueCustomerCollect clueCustomerCollect, DealerCustomer customerResponse,
                                       DefeatApprovalOperateRecord approvalOperateRecord, FailStatusEnum failStatusEnum,
                                       Date distributeTime) {
        switch (failStatusEnum) {
            case AGREE:
                //同意战败-更新计划跟进记录全部为null
                clueCustomerCollect.setPlanFollowTime(null);
                clueCustomerCollect.setPlanFollowId(null);
                clueCustomerCollect.setPlanFollowTimeCode(null);
                clueCustomerCollect.setPlanFollowContent(null);
                //customerCollect.setClueStatus(ClueStatsEnum.IS_FAIL.getCode());
                clueCustomerCollect.setFailStatus(FailStatusEnum.AGREE.getCode());
                clueCustomerCollect.setApproveCreatedTime(approvalOperateRecord.getCreateTime());
                break;
            case REFUSE:
                clueCustomerCollect.setFollowEmpId(customerResponse.getFollowEmpId());
                clueCustomerCollect.setFollowEmpName(customerResponse.getFollowEmpName());
                clueCustomerCollect.setDistributeTime(approvalOperateRecord.getCreateTime());
                //customerCollect.setClueStatus(clueFail.getClueStatus());
                clueCustomerCollect.setFailStatus(FailStatusEnum.REFUSE.getCode());
                clueCustomerCollect.setApproveCreatedTime(approvalOperateRecord.getCreateTime());
                break;
            case ACTIVATE:
                clueCustomerCollect.setFollowEmpId(customerResponse.getFollowEmpId());
                clueCustomerCollect.setFollowEmpName(customerResponse.getFollowEmpName());
                clueCustomerCollect.setDistributeTime(distributeTime);
                //clueCustomerCollect.setClueStatus(clueFail.getClueStatus());
                //clueCustomerCollect.setApproveRemark(request.getApproveRemark());
                clueCustomerCollect.setFailStatus(FailStatusEnum.ACTIVATE.getCode());
                //clueCustomerCollect.setPlanFollowTime(followPlanResponse.getPlanFollowTime());
                //clueCustomerCollect.setPlanFollowId(followPlanResponse.getId());
                //collectRequest.setPlanFollowContent(followPlanResponse.getPlanFollowContent());
                break;
            default:
                break;
        }
    }

    /**
     * crm线索跟进历史同步，线索审批记录更新线索战败申请记录
     *
     * @param request
     * @param clue
     * @param approvalResult
     * @param clueFail
     */
    private void updateClueFail(ClueRecordSyncRequest request, Clue clue, Integer approvalResult, ClueFail clueFail) {
        ClueFail updateClueFail = new ClueFail();
        updateClueFail.setStatus(approvalResult);
        updateClueFail.setDeleted(DeleteEnum.INIT.getFlag());
        // TODO: 2022/2/23 CRM同步没有审批备注
//                        updateClueFail.setApproveRemark();
        updateClueFail.setId(clueFail.getId());
        int result = clueFailManager.update(updateClueFail);
        if (result <= 0) {
            log.error("战败审批跟进记录更新战败申请记录失败，CRM线索ID：【{}】，SCRM线索ID：【{}】", request.getLeadId(), clue.getId());
            //throw new BusinessException(NEError.BUSINESS_ERROR, "线索历史记录同步，更新战败信息审批状态失败");
        }
    }

    /**
     * 战败申请添加记录
     *
     * @param clue
     * @param clue
     * @param defeatOperateRecord
     */
    private ClueFail handleClueFail(Clue clue, DefeatOperateRecord defeatOperateRecord,
                                List<EmployeeResponse> employeeList, EmployeeResponse historyEmp) {
        //拿到操作人
        EmployeeResponse employee = new EmployeeResponse();
        log.info("根据申请战败的操作人企微ID查询SCRM的empId，企微ID：【{}】", defeatOperateRecord.getWxUserId());
        if (StringUtils.isNotBlank(defeatOperateRecord.getWxUserId())) {
            Optional<EmployeeResponse> first = employeeList.stream().filter(item -> Objects.equals(item.getUserid(), defeatOperateRecord.getWxUserId())).findFirst();
            if (first.isPresent()) {
                employee = first.get();
            } else {
                employee.setName(historyEmp.getName());
                employee.setId(historyEmp.getId());
                //throw new BusinessException(NEError.BUSINESS_ERROR, "线索历史记录同步，查询战败申请的操作人数据为空");
            }
        }

        ClueFail clueFail = new ClueFail();
        clueFail.setClueId(clue.getId());
        clueFail.setFollowEmpId(employee.getId());
        clueFail.setClueStatus(clue.getStatus());

        switch (defeatOperateRecord.getLoseType()) {
            case 4:
                //选择竞品
                clueFail.setFailReasonCodes(FailReasonEnum.FAIL_REASON_002.getCode());
                break;
            case 8:
                //同城战败
                clueFail.setFailReasonCodes(FailReasonEnum.FAIL_REASON_003.getCode());
                break;
            case 7:
                //异地客户
                clueFail.setFailReasonCodes(FailReasonEnum.FAIL_REASON_007.getCode());
                break;
            case 6:
                //品牌价值
                clueFail.setFailReasonCodes(FailReasonEnum.FAIL_REASON_004.getCode());
                break;
            case 11:
            case 2:
                //金融方案，价格
                clueFail.setFailReasonCodes(FailReasonEnum.FAIL_REASON_005.getCode());
                break;
            case 1:
            case 5:
            case 10:
            case 12:
            case 13:
            case 14:
            case 15:
            case 16:
            case 17:
            case 18:
                clueFail.setFailReasonCodes(FailReasonEnum.FAIL_REASON_006.getCode());
                break;
            default:
                clueFail.setFailReasonCodes(FailReasonEnum.FAIL_REASON_001.getCode());
                break;
        }

        clueFail.setFailRemark(defeatOperateRecord.getFeedback());
        clueFail.setStatus(FailStatusEnum.APPROVAL_PENDING.getCode());
        clueFail.setTenantId(clue.getTenantId());
        clueFail.setDealerId(clue.getDealerId());
        clueFail.setCorpId(clue.getCorpId());
        clueFail.setCreatedName(employee.getName());
        clueFail.setCreatedTime(defeatOperateRecord.getCreateTime());
        clueFail.setUpdatedTime(defeatOperateRecord.getUpdateTime());
        clueFail.setDeleted(DeleteEnum.INIT.getFlag());
        clueFailManager.insert(clueFail);
        return clueFail;
    }

    /**
     * 处理线索订单信息
     *
     * @param clue
     * @param customerResponse
     * @param orderOperateRecord
     */
    private Long handleClueOrder(Clue clue, DealerCustomer customerResponse, OrderOperateRecord orderOperateRecord, List<ClueIntentionVehicle> vehicleList,
                                 List<EmployeeResponse> employeeList, EmployeeResponse historyEmp) {
        //拿到操作人
        String operaName = null;
        String operaId = null;
        if (StringUtils.isNotBlank(orderOperateRecord.getWxUserId())) {
            Optional<EmployeeResponse> first = employeeList.stream().filter(item -> Objects.equals(item.getUserid(), orderOperateRecord.getWxUserId())).findFirst();
            if (first.isPresent()) {
                EmployeeResponse employeeResponse = first.get();
                operaId = employeeResponse.getId().toString();
                operaName = employeeResponse.getName();
            } else {
                operaId = historyEmp.getId() == null ? null : historyEmp.getId().toString();
                operaName = historyEmp.getName();
            }
        }

        //查询线索的意向信息
        ClueIntentionVehicle vehicle = new ClueIntentionVehicle();
        if (CollectionUtils.isNotEmpty(vehicleList)) {
            vehicle = vehicleList.get(0);
        }

        //新建订单信息
        ClueOrder orderRequest = new ClueOrder();
        orderRequest.setClueId(clue.getId());
        orderRequest.setName(customerResponse.getName());
        orderRequest.setPhone(customerResponse.getPhone());
        orderRequest.setOrderBrandId(StringUtils.isBlank(vehicle.getBrandId()) ? null : Long.valueOf(vehicle.getBrandId()));
        orderRequest.setOrderBrandName(vehicle.getBrandName());
        orderRequest.setOrderSeriesId(StringUtils.isBlank(vehicle.getSeriesId()) ? null : Long.valueOf(vehicle.getSeriesId()));
        orderRequest.setOrderSeriesName(vehicle.getSeriesName());
        orderRequest.setOrderYearId(StringUtils.isBlank(vehicle.getModelYearId()) ? null : Long.valueOf(vehicle.getModelYearId()));
        orderRequest.setOrderModelYearName(vehicle.getModelYearName());
        orderRequest.setOrderModelId(StringUtils.isBlank(vehicle.getModelId()) ? null : Long.valueOf(vehicle.getModelId()));
        orderRequest.setOrderConfigId(StringUtils.isBlank(vehicle.getConfigId()) ? null : Long.valueOf(vehicle.getConfigId()));
        orderRequest.setOrderModelName(vehicle.getModelName());
        orderRequest.setOrderConfigName(vehicle.getConfigName());
        orderRequest.setOrderName(orderOperateRecord.getCustomerName());
        orderRequest.setOrderPhone(orderOperateRecord.getPhone());
        orderRequest.setOrderMoney(new BigDecimal(orderOperateRecord.getOrderMoney()));
        orderRequest.setOrderDeliveryTime(orderOperateRecord.getCarApplyDate());
        orderRequest.setOrderAddress(orderOperateRecord.getAddress());
        // TODO: 2022/2/23 根据线索状态判断订单状态
        ClueStatsEnum clueStatsEnum = ClueStatsEnum.getClueStatusByCode(clue.getStatus());
        switch (clueStatsEnum) {
            case ORDER:
                orderRequest.setStatus(ClueOrderStatusEnum.ORDERED.getCode());
                break;
            case DELIVERY:
                orderRequest.setStatus(ClueOrderStatusEnum.DELIVERY.getCode());
                break;
            case CONSUMED:
                orderRequest.setStatus(ClueOrderStatusEnum.CONSUMED.getCode());
                break;
            default:
                orderRequest.setStatus(ClueOrderStatusEnum.ORDERED.getCode());
                break;
            // TODO: 2022/2/23 取消订单暂无触发
        }

        ClueOrder orderQueryRequest = new ClueOrder();
        orderQueryRequest.setClueId(clue.getId());
        orderQueryRequest.setDeleted(DeleteEnum.INIT.getFlag());
        OrderField orderField = new OrderField("id", "desc");
        orderQueryRequest.setOrderFields(Lists.newArrayList(orderField));
        ClueOrderResponse orderResponse = clueOrderService.getOneByParam(orderQueryRequest);

        Integer result;
        if (EmptyUtils.isEmpty(orderResponse)) {
            orderRequest.setTenantId(clue.getTenantId());
            orderRequest.setDealerId(clue.getDealerId());
            orderRequest.setDealerId(clue.getDealerId());
            orderRequest.setCorpId(clue.getCorpId());
            orderRequest.setDeleted(DeleteEnum.INIT.getFlag());
            orderRequest.setCreatedName(operaName);
            orderRequest.setCreatedBy(operaId);
            orderRequest.setCreatedTime(orderOperateRecord.getCreateTime());
            result = clueOrderService.insert(orderRequest);
        } else {
            orderRequest.setId(orderResponse.getId());
            orderRequest.setUpdatedName(operaName);
            orderRequest.setUpdatedBy(operaId);
            orderRequest.setUpdatedTime(orderOperateRecord.getUpdateTime());
            result = clueOrderService.update(orderRequest);
        }
        if (result <= 0) {
            log.error("CRM同步线索跟进数据，下订状态，处理订单信息，保存或更新订单信息失败");
            //throw new BusinessException(NEError.BUSINESS_ERROR, "CRM同步线索跟进数据，下订状态，处理订单信息，保存或更新订单信息失败");
        }
        return orderRequest.getId();
    }

    private void handleIdCard(DealerCustomer customerResponse, PredictOperateRecord predictOperateRecord, Clue clue,
                              List<EmployeeResponse> employeeList, EmployeeResponse historyEmp) {
        if (StringUtils.isNotBlank(predictOperateRecord.getIdCard())) {
            //拿到操作人
            String operaName = null;
            String operaId = null;
            if (StringUtils.isNotBlank(predictOperateRecord.getWxUserId())) {
                Optional<EmployeeResponse> first = employeeList.stream().filter(item -> Objects.equals(item.getUserid(), predictOperateRecord.getWxUserId())).findFirst();
                if (first.isPresent()) {
                    EmployeeResponse employeeResponse = first.get();
                    operaId = employeeResponse.getId().toString();
                    operaName = employeeResponse.getName();
                } else {
                    operaId = historyEmp.getId() == null ? null : historyEmp.getId().toString();
                    operaName = historyEmp.getName();
                }
            }
            //身份证号不为空
            AddCertificateInfoRequest certificateInfo = new AddCertificateInfoRequest();
            certificateInfo.setOneId(StringUtils.isBlank(customerResponse.getOneId()) ? null : Long.valueOf(customerResponse.getOneId()));
            certificateInfo.setCusId(customerResponse.getCustomerBaseId());
            certificateInfo.setName(predictOperateRecord.getCustName());
            // TODO: 2022/2/23 目前数据都为空，暂时不做转换处理
            certificateInfo.setSex(predictOperateRecord.getGender());
//                            certificateInfo.setNation();
//                            certificateInfo.setBirth();
            certificateInfo.setAddress(predictOperateRecord.getAddress());
            certificateInfo.setCardId(predictOperateRecord.getIdCard());
//                            certificateInfo.setNationality();
//                            certificateInfo.setFirstIssueDate();
//                            certificateInfo.setQuasiDrivingType();
//                            certificateInfo.setStartValidityDate("");
//                            certificateInfo.setEndValidityDate();
//                            certificateInfo.setDataSources();
            certificateInfo.setUrl(predictOperateRecord.getIdCardUrl());
            certificateInfo.setCertificateType(CertificateEnum.ID_CARD.getCode());

            QueryCertificateInfoRequest queryCertificateInfoRequest = new QueryCertificateInfoRequest();
            queryCertificateInfoRequest.setOneId(Long.valueOf(customerResponse.getOneId()));
            queryCertificateInfoRequest.setDeleted(DeleteEnum.INIT.getFlag());
            queryCertificateInfoRequest.setCertificateType(CertificateEnum.ID_CARD.getCode());
            log.info("调用mdQuery 查询证件表,入参：{}", JsonUtils.object2JSON(queryCertificateInfoRequest));
            CertificateInfoResponse certificateInfoResponse = mdQueryClient.getOneByParam(queryCertificateInfoRequest).getData();
            if (certificateInfoResponse != null) {
                Long id = certificateInfoResponse.getId();
                certificateInfo.setId(id);
                certificateInfo.setUpdatedName(operaName);
                certificateInfo.setUpdatedTime(predictOperateRecord.getUpdateTime());
                certificateInfo.setUpdatedBy(operaId);
                log.info("调用mdWrite update证件表,入参：{}", JsonUtils.object2JSON(certificateInfo));
                mdWriteClient.update(BeanUtil.copy(certificateInfo, UpdateCertificateInfoRequest.class));
            } else {
                certificateInfo.setDeleted(DeleteEnum.INIT.getFlag());
                certificateInfo.setCreatedBy(operaName);
                certificateInfo.setCreatedName(operaId);
                certificateInfo.setCreatedTime(predictOperateRecord.getCreateTime());
                certificateInfo.setDealerId(clue.getDealerId());
                certificateInfo.setTenantId(clue.getTenantId());
                certificateInfo.setCorpId(clue.getCorpId());
                log.info("调用mdWrite add证件表,入参：{}", JsonUtils.object2JSON(certificateInfo));
                mdWriteClient.add(certificateInfo);
            }
        }
    }

    private void handleDriving(DealerCustomer customerResponse, PredictOperateRecord predictOperateRecord, Clue clue
            , List<EmployeeResponse> employeeList, EmployeeResponse historyEmp) {
        if (StringUtils.isNotBlank(predictOperateRecord.getDrivingLicense())) {
            //拿到操作人
            String operaName = null;
            String operaId = null;
            if (StringUtils.isNotBlank(predictOperateRecord.getWxUserId())) {
                Optional<EmployeeResponse> first = employeeList.stream().filter(item -> Objects.equals(item.getUserid(), predictOperateRecord.getWxUserId())).findFirst();
                if (first.isPresent()) {
                    EmployeeResponse employeeResponse = first.get();
                    operaId = employeeResponse.getId().toString();
                    operaName = employeeResponse.getName();
                } else {
                    operaId = historyEmp.getId() == null ? null : historyEmp.getId().toString();
                    operaName = historyEmp.getName();
                }
            }

            //驾驶证不为空
            AddCertificateInfoRequest certificateInfo = new AddCertificateInfoRequest();
            certificateInfo.setOneId(StringUtils.isBlank(customerResponse.getOneId()) ? null : Long.valueOf(customerResponse.getOneId()));
            certificateInfo.setCusId(customerResponse.getCustomerBaseId());
            certificateInfo.setName(predictOperateRecord.getCustName());
            // TODO: 2022/2/23 目前数据都为空，暂时不做转换处理
            certificateInfo.setSex(predictOperateRecord.getGender());
//                            certificateInfo.setNation();
//                            certificateInfo.setBirth();
            certificateInfo.setAddress(predictOperateRecord.getAddress());
            //驾驶证填充身份证号字段为驾驶证
            certificateInfo.setCardId(predictOperateRecord.getDrivingLicense());
//                            certificateInfo.setNationality();
//                            certificateInfo.setFirstIssueDate();
//                            certificateInfo.setQuasiDrivingType();
//                            certificateInfo.setStartValidityDate("");
//                            certificateInfo.setEndValidityDate();
//                            certificateInfo.setDataSources();
            certificateInfo.setUrl(predictOperateRecord.getDrivingLicenseUrl());
            certificateInfo.setCertificateType(CertificateEnum.DRIVER_LICENSE.getCode());

            QueryCertificateInfoRequest queryCertificateInfoRequest = new QueryCertificateInfoRequest();
            queryCertificateInfoRequest.setOneId(Long.valueOf(customerResponse.getOneId()));
            queryCertificateInfoRequest.setDeleted(DeleteEnum.INIT.getFlag());
            queryCertificateInfoRequest.setCertificateType(CertificateEnum.DRIVER_LICENSE.getCode());
            log.info("调用mdQuery 查询证件表,入参：{}", JsonUtils.object2JSON(queryCertificateInfoRequest));
            CertificateInfoResponse certificateInfoResponse = mdQueryClient.getOneByParam(queryCertificateInfoRequest).getData();
            if (certificateInfoResponse != null) {
                Long id = certificateInfoResponse.getId();
                certificateInfo.setId(id);
                certificateInfo.setUpdatedName(operaName);
                certificateInfo.setUpdatedTime(predictOperateRecord.getUpdateTime());
                certificateInfo.setUpdatedBy(operaId);
                log.info("调用mdWrite update证件表,入参：{}", JsonUtils.object2JSON(certificateInfo));
                mdWriteClient.update(BeanUtil.copy(certificateInfo, UpdateCertificateInfoRequest.class));
            } else {
                certificateInfo.setDeleted(DeleteEnum.INIT.getFlag());
                certificateInfo.setCreatedBy(operaId);
                certificateInfo.setCreatedName(operaName);
                certificateInfo.setCreatedTime(predictOperateRecord.getCreateTime());
                certificateInfo.setDealerId(clue.getDealerId());
                certificateInfo.setTenantId(clue.getTenantId());
                certificateInfo.setCorpId(clue.getCorpId());
                log.info("调用mdWrite add证件表,入参：{}", JsonUtils.object2JSON(certificateInfo));
                mdWriteClient.add(certificateInfo);
            }
        }
    }

    private VehicleSeriesResponse getSeriesByName(String seriesName) {
        VehicleSeriesResponse seriesResponse = new VehicleSeriesResponse();
        if (StringUtils.isBlank(seriesName)) {
            return seriesResponse;
        }
        QueryVehicleSeriesRequest seriesRequest = new QueryVehicleSeriesRequest();
        seriesRequest.setName(seriesName);
        Response<VehicleSeriesResponse> response = mdQueryClient.getOneSeriesByParam(seriesRequest);
        log.info("调用主数据根据车系名称查询车系，参数：【{}】，返回：【{}】", JSON.toJSONString(seriesRequest), JSON.toJSONString(response));
        if (Objects.nonNull(response) && response.getCode() == 0 && Objects.nonNull(response.getData())) {
            seriesResponse = response.getData();
        }
        return seriesResponse;
    }

    private VehicleBrandResponse getBrandById(Long brandId) {
        VehicleBrandResponse vehicleBrandResponse = new VehicleBrandResponse();
        if (brandId == null) {
            return vehicleBrandResponse;
        }
        QueryVehicleBrandRequest brandRequest = new QueryVehicleBrandRequest();
        brandRequest.setId(brandId);
        Response<List<VehicleBrandResponse>> response = mdQueryClient.getListByParam(brandRequest);
        log.info("调用主数据根据品牌ID查询品牌信息，参数：【{}】，返回：【{}】", JSON.toJSONString(brandRequest), JSON.toJSONString(response));
        if (Objects.nonNull(response) && response.getCode() == 0 && CollectionUtils.isNotEmpty(response.getData())) {
            vehicleBrandResponse = response.getData().get(0);
        }
        return vehicleBrandResponse;
    }

    private VehicleModelResponse getModelByName(String modelName) {
        VehicleModelResponse modelResponse = new VehicleModelResponse();
        if (StringUtils.isBlank(modelName)) {
            return modelResponse;
        }
        QueryVehicleModelRequest modelRequest = new QueryVehicleModelRequest();
        modelRequest.setName(modelName);
        Response<VehicleModelResponse> response = mdQueryClient.getOneModelByParam(modelRequest);
        log.info("调用主数据根据车型名称查询车型，参数：【{}】，返回：【{}】", JSON.toJSONString(modelRequest), JSON.toJSONString(response));
        if (Objects.nonNull(response) && response.getCode() == 0 && Objects.nonNull(response.getData())) {
            modelResponse = response.getData();
        }
        return modelResponse;
    }
}
